<?php
/**
 * Created by PhpStorm.
 * User: xpz
 * Date: 2023/8/23
 * Time: 13:57
 */

namespace app\api\command;

use think\console\Command;
use think\console\Input;
use think\console\input\Option;
use think\console\Output;
use think\Exception;
use think\config;
use think\Db;
use WebSocket\Client;

class Ai extends Command
{
    protected $search = ['*','-','###','\n','#','##'];
    protected $replace = ["","","","<br/>",'',''];
    protected function configure()
    {
        $this->setName('ai')              		//定义命令的名字
        ->setDescription('ai')      //定义命令的描述
        ->addArgument('method')                   //参数1
        ->addArgument('id');                    //文章id
    }

    //php think ai create(publish)
    protected function execute(Input $input, Output $output)
    {

        ini_set('max_execution_time', 600);//秒为单位，自己根据需要定义
//        require EXTEND_PATH.'/websocket/lib/Client.php';
        $method = $input->getArgument('method');
        if($method == 'create'){
            $this->create();
        } else if($method == 'test'){
            $this->update();
//            $this->xfyuyin();
//            $title = "危险派对 歌词";
//            $content = $this->xfyun($title);
//            echo $content;
        } else if($method == 'jita'){
            $this->create('吉他');
        } else if($method == 'gangqin'){
            $this->create('钢琴');
        }
    }




    protected function ticheck(){
        $nowH = (int)date("H",time());
        if($nowH < 8 || $nowH > 22){
            echo "不在提交时间内！";exit;
        }
    }

    private function create($tag){
//        $title = "写一篇关于放风筝的小学三年级,写事,叙事的作文，字数要求300字";
//        $content = $this->xfyun($title);
        $this->ticheck();
//        //延时0 到400秒
        $randTime = rand(0,200);
        echo "需要延时：".$randTime."\r\n";
        sleep($randTime);
        $keywordsModel = Model('app\common\model\BaiduKeywords');
        $categoryModel = Model('app\common\model\Category');
        $rs = $keywordsModel->where(['is_use'=>0,'tag'=>$tag,'cishu'=>0])->where('name','like',"%".$tag . "%")->limit(1)->select();
        echo $keywordsModel->getLastSql()."\r\n";
//        exit;
        if(!empty($rs)){
            foreach($rs as $k=>$v){
                echo $v['id']."=>".$v['name']."开始\r\n";
                try{
                    $content = $this->xfyun($v['name'].",关于".$v['tag']);
                    //                var_dump($content);
                    $contentArr = explode("\n\n",$content);
                    if(empty($contentArr)){
                        $contentArr = explode("\n",$content);
                    }
//                print_r($contentArr);exit;
//                exit;
                    array_pop($contentArr);
                    $returnContent = '';
                    if(!empty($contentArr)){
                        foreach($contentArr as $key=>$val){
                            if (strpos($val, '标题') !== false) {
//                                echo "字符串包含目标子字符串";
                            } else {
                                $val = str_replace($this->search,$this->replace,$val);
                                $returnContent .="<p>".$val."</p>";
                            }

                        }
                    }
                    if(empty($returnContent)){
                        $content = str_replace($this->search,$this->replace,$content);
                        $returnContent = "<p>".$content."</p>";;
                    }

                    var_dump($returnContent);
//                $content = str_replace("\n\n","</p><p>",$content);
//
//                $content = "<p>".$content."</p>";
//                var_dump($content);
//                exit;
                    $time = time();
                    $savaData = [
                        'content'=> $returnContent,
                        'title' => $v['name'],
                        'summary' => str_cut($returnContent),
                        'tag' => $v['tag'],
                        'createtime' => $time,
                        'updatetime' => $time,
                    ];
                    $categoryData = $categoryModel->where(['pid'=>14,'name'=>$v['tag']])->find();
//                echo $categoryModel->getLastSql();
//                print_r($categoryData);exit;
                    if(!empty($categoryData)){
                        $savaData['category_id'] = $categoryData['id'];
                        $savaData['category_pid'] = $categoryData['pid'];
                    }
//                print_r($savaData);exit;
                    $this->insert($savaData);

                    $keywordsModel->where(['id'=>$v['id']])->update(['is_use'=>1]);

                    echo $v['name']."结束\r\n";
                    sleep(1);
                } catch (\Exception $e) {
                    $keywordsModel->where(['id'=>$v['id']])->setInc('cishu',1);
                    echo $keywordsModel->getLastSql()."\r\n";
                    echo "2";
                    echo $e->getMessage();
                }


            }
        } else {
            echo "没有内容生成！\r\n";
        }
    }

    private function insert($data){

        $articleModel = Model('app\common\model\Article');
        $content = $data['content'];
        unset($data['content']);
        $id = $articleModel->insertGetId($data);
        $contentArr = [
            'aid'=>$id,
            'content'=>$content,
        ];
        Model('app\common\model\ArticleContent')->insertGetId($contentArr);


    }

    private function xfyun($title){
        //讯飞账号：16632327172
        $addr = "wss://spark-api.xf-yun.com/v1.1/chat";
//        $addr = "wss://spark-api.xf-yun.com/v3.1/chat";
//        $addr = "wss://spark-api.xf-yun.com/v2.1/chat";
//        $addr = "wss://spark-api.xf-yun.com/v1.1/chat";
        //密钥信息，在开放平台-控制台中获取：https://console.xfyun.cn/services/cbm
        $Appid = "7f481a8c";
        $Apikey = "06e8cea21012302b29ade67f7ee53a79";
        // $XCurTime =time();
        $ApiSecret ="MWViMzNjOWE5ODJkZDJlYzkyZWJkZmI4";
        // $XCheckSum ="";

        // $data = $this->getBody("你是谁？");
        $authUrl = $this->assembleAuthUrl("GET",$addr,$Apikey,$ApiSecret);
//        print_r($authUrl);exit;
        //创建ws连接对象
        $client = new Client($authUrl);


        // 连接到 WebSocket 服务器
        if ($client) {
            // 发送数据到 WebSocket 服务器
            $data = $this->getBody($Appid,$title);
            $client->send($data);

            // 从 WebSocket 服务器接收数据
            $answer = "";
            while(true){
                $response = $client->receive();
                $resp = json_decode($response,true);
                $code = $resp["header"]["code"];
//                echo "从服务器接收到的数据： " . $response;
                if(0 == $code){
                    $status = $resp["header"]["status"];
                    if($status != 2){
                        $content = $resp['payload']['choices']['text'][0]['content'];
                        $answer .= $content;
                    }else{
                        $content = $resp['payload']['choices']['text'][0]['content'];
                        $answer .= $content;
                        $total_tokens = $resp['payload']['usage']['text']['total_tokens'];
                        print("\r\n本次消耗token用量：\r\n");
                        print($total_tokens."\r\n");
                        break;
                    }
                }else{
                    echo "服务返回报错".$response;
                    break;
                }
            }

//            print("\r\n返回结果为：\r\n");
//            print($answer);
            return $answer;
        } else {
            echo "无法连接到 WebSocket 服务器";
        }



    }


    /**
     * 发送post请求
     * @param string $url 请求地址
     * @param array $post_data post键值对数据
     * @return string
     */
    private function http_request($url, $post_data, $headers) {
        $postdata = http_build_query($post_data);
        $options = array(
            'http' => array(
                'method' => 'POST',
                'header' => $headers,
                'content' => $postdata,
                'timeout' => 15 * 60 // 超时时间（单位:s）
            )
        );
        $context = stream_context_create($options);
        $result = file_get_contents($url, false, $context);

        echo $result;

        return "success";
    }

    //构造参数体
    private function getBody($appid,$question){
        $header = array(
            "app_id" => $appid,
            "uid" => "12345"
        );

        $parameter = array(
            "chat" => array(
//                "domain" => "general",
//                "domain" => "generalv2",
                "domain" => "lite",
                "temperature" => 0.5,
                "max_tokens" => 1024
            )
        );

        $payload = array(
            "message" => array(
                "text" => array(
                    // 需要联系上下文时，要按照下面的方式上传历史对话
                    // array("role" => "user", "content" => "你是谁"),
                    // array("role" => "assistant", "content" => "....."),
                    // ...省略的历史对话
                    array("role" => "user", "content" => $question)
                )
            )
        );

        $json_string = json_encode(array(
            "header" => $header,
            "parameter" => $parameter,
            "payload" => $payload
        ));

        return $json_string;

    }

    //鉴权方法
    private function assembleAuthUrl($method, $addr, $apiKey, $apiSecret) {
        if ($apiKey == "" && $apiSecret == "") { // 不鉴权
            return $addr;
        }

        $ul = parse_url($addr); // 解析地址
        if ($ul === false) { // 地址不对，也不鉴权
            return $addr;
        }

        // // $date = date(DATE_RFC1123); // 获取当前时间并格式化为RFC1123格式的字符串
        $timestamp = time();
        $rfc1123_format = gmdate("D, d M Y H:i:s \G\M\T", $timestamp);
        // $rfc1123_format = "Mon, 31 Jul 2023 08:24:03 GMT";


        // 参与签名的字段 host, date, request-line
        $signString = array("host: " . $ul["host"], "date: " . $rfc1123_format, $method . " " . $ul["path"] . " HTTP/1.1");

        // 对签名字符串进行排序，确保顺序一致
        // ksort($signString);

        // 将签名字符串拼接成一个字符串
        $sgin = implode("\n", $signString);
//        print( $sgin);

        // 对签名字符串进行HMAC-SHA256加密，得到签名结果
        $sha = hash_hmac('sha256', $sgin, $apiSecret,true);
//        print("signature_sha:\n");
//        print($sha);
        $signature_sha_base64 = base64_encode($sha);

        // 将API密钥、算法、头部信息和签名结果拼接成一个授权URL
        $authUrl = "api_key=\"$apiKey\", algorithm=\"hmac-sha256\", headers=\"host date request-line\", signature=\"$signature_sha_base64\"";

        // 对授权URL进行Base64编码，并添加到原始地址后面作为查询参数
        $authAddr = $addr . '?' . http_build_query(array(
                'host' => $ul['host'],
                'date' => $rfc1123_format,
                'authorization' => base64_encode($authUrl),
            ));

        return $authAddr;
    }


    /**
     * 文字转语音
     * @return array
     * @throws \WebSocket\BadOpcodeException
     * @throws \WebSocket\ConnectionException
     */
    public function xfyuyin(){
//        include_once IFlytek\Xfyun\
//        \think\Loader::addNamespace([
//            'iflytekop' => VENDOR_PATH . 'iflytekop/xfyun-speech/src',
////            'GatewayWorker' =>VENDOR_PATH . 'workerman/gateway-worker/src',
//        ]);
//        include_once VENDOR_PATH."iflytekop/xfyun-speech/src/TtsClient.php";
        $appId = '12654f2b';// 需要填入app_id
        $apiKey = '03b28d1be1f33faa1d260a5e0ff8e47d';// 需要填入api_key
        $apiSecret = 'MGIwNjk2MjZlMGExMzkyOGE0MjhjY2M5';// 需要填入api_secret

        $params['aue'] = '.raw';
        //最少九个字
//        $text = "我也不想买啊可是这也太便宜了[p900]";
//        $text = '毕竟大火的钱也不是大风刮来的[p900]';
//        $text = '看一下这台木工雕刻机[p900]';
        $text = "我也不想买啊可是这也太便宜了[p900]毕竟大火的钱也不是大风刮来的[p900]看一下这台木工雕刻机[p900]评论区扣一我告诉你多少钱[p900]";
        $tts = new Tts();
        $url = $tts->createAuthUrl($apiKey, $apiSecret, time());
//        echo $url;exit;
        $client = new Client($url);
//        print_r($client);exit;
        $message = $tts->createMsg(
            $appId,
            $text
        );
//        print_r($message);exit;
        try {
            $client->send(json_encode($message, true));
            $date = date('YmdHis', time());
            $file_name = $date . ($params['aue'] === 'raw' ? '.pcm' : '.mp3');
            $folder = '/uploads/tts/';
            //判断文件夹是否存在
            if (!is_dir(ROOT_PATH . 'public' . $folder)) {
                @mkdir(ROOT_PATH . 'public' . $folder);
            }
            $audio_file = fopen(ROOT_PATH . 'public' . $folder . $file_name, 'ab');
            $response = $client->receive();
//            print_r($response);exit;
            $response = json_decode($response, true);
            do {
                if ($response['code']) {
                    return $response;
                }
                //返回的音频需要进行base64解码
                $audio = base64_decode($response['data']['audio']);
                fwrite($audio_file, $audio);
                // 第一次消息就收到结束标志的情况
                if ($response['data']['status'] == 2) {
                    fclose($audio_file);
                    $client->close();
                    $return = [
                        'code' => 0,
                        'msg'  => '合成成功',
                        'data' => [
                            'url'      => $folder . $file_name,
                            'filesize' => filesize(ROOT_PATH . 'public' . $folder . $file_name)
                        ]
                    ];
                }
                //继续接收消息
                $response = $client->receive();
                $response = json_decode($response, true);
            } while ($response['data']['status'] != 2);
            fclose($audio_file);
            $return = [
                'code' => 0,
                'msg'  => '合成成功',
                'data' => [
                    'url'      => $folder . $file_name,
                    'filesize' => filesize(ROOT_PATH . 'public' . $folder . $file_name)
                ]
            ];
            print_r($return);
        } catch (Exception $e) {
            return [
                'code' => 1,
                'msg'  => $e->getMessage(),
            ];
        } finally {
            $client->close();
        }





//        $client = new \IFlytek\Xfyun\Speech\TtsClient($appId, $apiKey, $apiSecret);
//        file_put_contents('./result.mp3', $client->request('欢迎使用科大讯飞语音能力，让我们一起用人工智能改变世界')->getBody());
    }


    public function update(){
        $articleModel = Model('app\common\model\Article');
//        $rs = $articleModel->where(['category_id'=>19,'id'=>['gt',4763],'summary'=>['eq','...']])->order('id asc')->limit(1)->select();
        $rs = $articleModel->where(['category_id'=>19,'summary'=>['eq','']])->order('id desc')->limit(1)->select();
//        $rs = $articleModel->where(['id'=>5120])->order('id desc')->limit(1)->select();
//            print_r($rs);exit;
        echo $articleModel->getLastSql();
        $articleContentModel = Model('app\common\model\ArticleContent');
        if(!empty($rs)){
            foreach($rs as $k=>$v){
                if($v['summary'] == ''){
                    sleep(3);
                    echo $v['id']."=>".$v['title']."--开始\r\n";
//                    echo $v['title'];exit;

                    $tag = $v['tag'];
                    $categoryId = $v['category_id'];

                    $searchTag = '钢琴';
                    if (strpos($v['title'], $searchTag) !== false) {
//                        echo "字符串中存在子字符串。";
                        $categoryId = 19;
                        $tag = '钢琴';
                    }

                    $searchTag = '吉他';
                    if (strpos($v['title'], $searchTag) !== false) {
//                        echo "字符串中存在子字符串。";
                        $categoryId = 15;
                        $tag = '吉他';
                    }
                    echo $v['id']."=>".$v['title'].",关于".$tag."--开始\r\n";

                    $content = $this->xfyun($v['title'].",关于".$tag);


//                var_dump($content);

                    $contentArr = explode("\n\n",$content);
                    if(empty($contentArr)){
                        $contentArr = explode("\n",$content);
                    }
                    print_r($contentArr);
                    array_pop($contentArr);
                    $returnContent = '';
                    if(!empty($contentArr)){
                        foreach($contentArr as $key=>$val){
                            if (strpos($val, '标题') !== false) {
//                                echo "字符串包含目标子字符串";
                            } else {
                                $val = str_replace($this->search,$this->replace,$val);
                                $returnContent .="<p>".$val."</p>";
                            }

                        }
                    }
                    if(empty($returnContent)){
                        $content = str_replace($this->search,$this->replace,$content);
                        $returnContent = "<p>".$content."</p>";;
                    }
//                    var_dump($returnContent);exit;
                    $articleModel->where(['id'=>$v['id']])->update(['summary'=>str_cut($returnContent),'tag'=>$tag,'category_id'=>$categoryId]);
                    echo $articleModel->getLastSql()."\r\n";
                    $articleContentModel->where(['aid'=>$v['id']])->update(['content'=>$returnContent]);
                    echo $articleContentModel->getLastSql()."\r\n";
                }
            }
        }
    }

}